﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace ST.Common.Util.Text
{
    public class TextHelper
    {
        public static string SerializeObject(object obj, string dateFormat = "yyyy-MM-dd HH:mm:ss")
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.NullValueHandling = NullValueHandling.Ignore;
            if (!string.IsNullOrEmpty(dateFormat))
            {
                settings.DateFormatString = dateFormat;
            }
            return JsonConvert.SerializeObject(obj, settings);
        }

        public static string GetString(string str)
        {
            if (str == null)
            {
                return string.Empty;
            }
            return str.Trim();
        }

        public static string GetString(JObject paras, string name)
        {
            if (paras == null || string.IsNullOrEmpty(name))
            {
                return string.Empty;
            }
            return paras.Value<string>(name);
        }

        public static bool GetBool(JObject paras, string name)
        {
            if (paras == null || string.IsNullOrEmpty(name))
            {
                return false;
            }
            return paras.Value<bool>(name);
        }

        public static bool GetBool(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return false;
            }
            if (bool.TryParse(str, out bool i))
            {
                return i;
            }
            return false;
        }

        /// <summary>
        /// 转换成bool？类型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool? GetBoolNullable(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return null;
            }
            if (bool.TryParse(str, out bool i))
            {
                return i;
            }
            return null;
        }

        /// <summary>
        /// 转换成bool？类型
        /// </summary>
        /// <param name="paras"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool? GetBoolNullable(JObject paras, string name)
        {
            if (paras == null || string.IsNullOrEmpty(name))
            {
                return null;
            }
            string value = paras.Value<string>(name);
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            if (bool.TryParse(value, out bool i))
            {
                return i;
            }
            return null;
        }

        #region 日期处理相关
        /// <summary>
        /// 处理开始日期
        /// </summary>
        /// <param name="paras"></param>
        /// <param name="name"></param>
        /// <param name="srcFormat"></param>
        /// <returns></returns>
        public static DateTime GetDateTimeStart(JObject paras, string name, string srcFormat = "yyyy-MM-dd")
        {
            if (paras == null || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(srcFormat))
            {
                return DateTime.MinValue;
            }
            string value = paras.Value<string>(name);
            return GetDateTimeStart(value, srcFormat);
        }

        /// <summary>
        /// 处理开始日期
        /// </summary>
        /// <param name="str"></param>
        /// <param name="srcFormat"></param>
        /// <returns></returns>
        public static DateTime GetDateTimeStart(string str, string srcFormat = "yyyy-MM-dd")
        {
            if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(srcFormat))
            {
                return DateTime.MinValue;
            }
            if (DateTime.TryParseExact(str, srcFormat, null, System.Globalization.DateTimeStyles.None, out DateTime dt))
            {
                return new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0);
            }
            else
            {
                return DateTime.MinValue;
            }
        }

        /// <summary>
        /// 处理开始日期
        /// </summary>
        /// <param name="paras"></param>
        /// <param name="name"></param>
        /// <param name="srcFormat"></param>
        /// <returns></returns>
        public static DateTime GetDateTimeEnd(JObject paras, string name, string srcFormat = "yyyy-MM-dd")
        {
            if (paras == null || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(srcFormat))
            {
                return DateTime.MinValue;
            }
            string value = paras.Value<string>(name);
            return GetDateTimeEnd(value, srcFormat);
        }

        /// <summary>
        /// 处理结束日期
        /// </summary>
        /// <param name="str"></param>
        /// <param name="srcFormat"></param>
        /// <returns></returns>
        public static DateTime GetDateTimeEnd(string str, string srcFormat = "yyyy-MM-dd")
        {
            if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(srcFormat))
            {
                return DateTime.MinValue;
            }
            if (DateTime.TryParseExact(str, srcFormat, null, System.Globalization.DateTimeStyles.None, out DateTime dt))
            {
                return new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59);
            }
            else
            {
                return DateTime.MinValue;
            }
        }

        /// <summary>
        /// 字符型日期转换
        /// </summary>
        /// <param name="str"></param>
        /// <param name="srcFormat"></param>
        /// <returns></returns>
        public static DateTime GetDateTime(JObject paras, string name, string srcFormat = "yyyy-MM-dd")
        {
            if (paras == null || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(srcFormat))
            {
                return DateTime.MinValue;
            }
            string value = paras.Value<string>(name);
            return GetDateTime(value, srcFormat);
        }

        /// <summary>
        /// 字符型日期转换
        /// </summary>
        /// <param name="str"></param>
        /// <param name="srcFormat"></param>
        /// <returns></returns>
        public static DateTime GetDateTime(string str, string srcFormat = "yyyy-MM-dd")
        {
            if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(srcFormat))
            {
                return DateTime.MinValue;
            }
            DateTime dt;
            if (DateTime.TryParseExact(str, srcFormat, null, System.Globalization.DateTimeStyles.None, out dt))
            {
                return dt;
            }
            else
            {
                return DateTime.MinValue;
            }
        }

        /// <summary>
        /// 获取指定日期，在为一年中为第几周
        /// </summary>
        /// <param name="dt">指定时间</param>
        /// <reutrn>返回第几周</reutrn>
        private static int GetWeekOfYear(DateTime dt, DayOfWeek firstDayOfWeek = DayOfWeek.Monday)
        {
            GregorianCalendar gc = new GregorianCalendar();
            int weekOfYear = gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, firstDayOfWeek);
            return weekOfYear;
        }

        /// <summary>
        /// 获取指定年月的第n周起始日期
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="weekNum"></param>
        /// <returns></returns>
        public static DateTime GetWeekStartByMonth(int year, int month, int weekNum)
        {
            throw new NotImplementedException();
            //DateTime dtMonthStart = new DateTime(year, month, 1);
            //DateTime dtMonthEnd = dtMonthStart.AddMonths(1).AddDays(-1);
            //GregorianCalendar gc = new GregorianCalendar();
        }

        /// <summary>
        /// 格式化日期
        /// </summary>
        /// <param name="ticks"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string FormatUTCTicks(long ticks, string format = "yyyy-MM-dd HH:mm:ss")
        {
            try
            {
                if (ticks <= 621356256000000000)
                {
                    return ticks.ToString();
                }
                var date = new DateTime(ticks);
                return date.ToString(format);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 格式化日期
        /// </summary>
        /// <param name="ticks"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string FormatJSUTCTicks(long ticks, string format = "yyyy-MM-dd HH:mm:ss")
        {
            try
            {
                if (ticks <= 621356256000000000)
                {
                    return ticks.ToString();
                }
                var date = new DateTime(ticks / 10000 - 62135625600000);
                return date.ToString(format);
            }
            catch
            {
                return string.Empty;
            }
        }
		#endregion

		#region 数字处理相关
		public static decimal GetDecimal(JObject paras, string name, decimal defValue = 0)
		{
			if (paras == null || string.IsNullOrEmpty(name))
			{
				return defValue;
			}
			string value = paras.Value<string>(name);
			if (string.IsNullOrEmpty(value))
			{
				return defValue;
			}
			if (decimal.TryParse(value, out decimal i))
			{
				return i;
			}
			return defValue;
		}

		/// <summary>
		/// 转换成decimal类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static decimal GetDecimal(string str, decimal defValue = 0)
		{
			if (string.IsNullOrEmpty(str))
			{
				return defValue;
			}
			if (decimal.TryParse(str, out decimal i))
			{
				return i;
			}
			return defValue;
		}

		/// <summary>
		/// 转换成decimal类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static decimal GetDecimalOrPercent(string str, decimal defValue = 0)
		{
			if (string.IsNullOrEmpty(str))
			{
				return defValue;
			}
			if (str.IndexOf('%') < 0)
			{
				if (decimal.TryParse(str.Replace(",", ""), out decimal i))
				{
					return i;
				}
			}
			else
			{
				if (decimal.TryParse(str.Substring(0, str.Length - 1), out decimal i))
				{
					return i / 100;
				}
			}

			return defValue;
		}

		/// <summary>
		/// 转换成decimal？类型
		/// </summary>
		/// <param name="paras"></param>
		/// <param name="name"></param>
		/// <returns></returns>
		public static decimal? GetDecimalNullable(JObject paras, string name)
		{
			if (paras == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			string value = paras.Value<string>(name);
			if (string.IsNullOrEmpty(value))
			{
				return null;
			}
			if (decimal.TryParse(value, out decimal i))
			{
				return i;
			}
			return null;
		}

		/// <summary>
		/// 转换成decimal?类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static decimal? GetDecimalNullable(string str)
		{
			if (string.IsNullOrEmpty(str))
			{
				return null;
			}
			if (decimal.TryParse(str, out decimal i))
			{
				return i;
			}
			return null;
		}

		/// <summary>
		/// 转换成int？类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static int? GetIntNullable(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return null;
            }
            if (int.TryParse(str, out int i))
            {
                return i;
            }
            return null;
        }

        /// <summary>
        /// 转换成int？类型
        /// </summary>
        /// <param name="paras"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static int? GetIntNullable(JObject paras, string name)
        {
            if (paras == null || string.IsNullOrEmpty(name))
            {
                return null;
            }
            string value = paras.Value<string>(name);
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            if (int.TryParse(value, out int i))
            {
                return i;
            }
            return null;
        }

        /// <summary>
        /// 转换成int类型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetInt(string str, int defValue = 0)
        {
            if (string.IsNullOrEmpty(str))
            {
                return defValue;
            }
            if (int.TryParse(str, out int i))
            {
                return i;
            }
            return defValue;
        }

        public static int[] GetInts(JObject paras, string name, char split = ',')
        {
            if (paras == null || string.IsNullOrEmpty(name))
            {
                return null;
            }
            string value = paras.Value<string>(name);
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            string[] values = value.Split(split, StringSplitOptions.RemoveEmptyEntries);
            if (values == null || values.Length == 0)
            {
                return null;
            }
            int[] ret = new int[values.Length];
            for (var i = 0; i < values.Length; i++)
            {
                int.TryParse(values[i], out ret[i]);
            }
            return ret;
        }

        public static int[] GetInts(string str, char split = ',')
        {
            if (string.IsNullOrEmpty(str))
            {
                return null;
            }
            string[] values = str.Split(split, StringSplitOptions.RemoveEmptyEntries);
            if (values == null || values.Length == 0)
            {
                return null;
            }
            int[] ret = new int[values.Length];
            for (var i = 0; i < values.Length; i++)
            {
                int.TryParse(values[i], out ret[i]);
            }
            return ret;
        }

        /// <summary>
        /// 转换成int类型
        /// </summary>
        /// <param name="paras"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static int GetInt(JObject paras, string name, int defValue = 0)
        {
            if (paras == null || string.IsNullOrEmpty(name))
            {
                return defValue;
            }
            string value = paras.Value<string>(name);
            if (string.IsNullOrEmpty(value))
            {
                return defValue;
            }
            if (int.TryParse(value, out int i))
            {
                return i;
            }
            return defValue;
        }

		/// <summary>
		/// 转换成long?类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static long? GetInt64Nullable(string str)
		{
			if (string.IsNullOrEmpty(str))
			{
				return null;
			}
			if (long.TryParse(str, out long i))
			{
				return i;
			}
			return null;
		}

		/// <summary>
		/// 转换成long?类型
		/// </summary>
		/// <param name="paras"></param>
		/// <param name="name"></param>
		/// <returns></returns>
		public static long? GetInt64Nullable(JObject paras, string name)
		{
			if (paras == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			string value = paras.Value<string>(name);
			if (string.IsNullOrEmpty(value))
			{
				return null;
			}
			if (long.TryParse(value, out long i))
			{
				return i;
			}
			return null;
		}

		/// <summary>
		/// 转换成long类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static long GetInt64(string str, long defValue = 0)
		{
			if (string.IsNullOrEmpty(str))
			{
				return defValue;
			}
			if (long.TryParse(str, out long i))
			{
				return i;
			}
			return defValue;
		}

		public static long[] GetInt64s(JObject paras, string name, char split = ',', bool removeZero = true)
		{
			try
			{
				if (paras == null || string.IsNullOrEmpty(name))
				{
					return null;
				}
				string value = paras.Value<string>(name);
				if (string.IsNullOrEmpty(value))
				{
					return null;
				}
				string[] values = value.Split(split, StringSplitOptions.RemoveEmptyEntries);
				if (values == null || values.Length == 0)
				{
					return null;
				}
				List<long> ret = new List<long>();
				for (var i = 0; i < values.Length; i++)
				{
					if (!long.TryParse(values[i], out long tmp))
					{
						continue;
					}
					if (tmp == 0 && removeZero)
					{
						continue;
					}
					ret.Add(tmp);
				}

				return ret.ToArray();
			}
			catch
			{
				return null;
			}
		}

		public static long[] GetInt64s(string str, char split = ',', bool removeZero = true)
		{
			try
			{
				if (string.IsNullOrEmpty(str))
				{
					return null;
				}
				string[] values = str.Split(split, StringSplitOptions.RemoveEmptyEntries);
				if (values == null || values.Length == 0)
				{
					return null;
				}
				List<long> ret = new List<long>();
				for (var i = 0; i < values.Length; i++)
				{
					if (!long.TryParse(values[i], out long tmp))
					{
						continue;
					}
					if (tmp == 0 && removeZero)
					{
						continue;
					}
					ret.Add(tmp);
				}
				return ret.ToArray();
			}
			catch
			{
				return null;
			}
		}

		/// <summary>
		/// 转换成long类型
		/// </summary>
		/// <param name="paras"></param>
		/// <param name="name"></param>
		/// <returns></returns>
		public static long GetInt64(JObject paras, string name, int defValue = 0)
		{
			if (paras == null || string.IsNullOrEmpty(name))
			{
				return defValue;
			}
			string value = paras.Value<string>(name);
			if (string.IsNullOrEmpty(value))
			{
				return defValue;
			}
			if (long.TryParse(value, out long i))
			{
				return i;
			}
			return defValue;
		}

		/// <summary>
		/// 转换成ushort类型
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static ushort GetUInt16(string str, ushort defValue = 0)
        {
            if (string.IsNullOrEmpty(str))
            {
                return defValue;
            }
            if (ushort.TryParse(str, out ushort i))
            {
                return i;
            }
            return defValue;
        }

		/// <summary>
		/// 四舍五入
		/// </summary>
		/// <returns></returns>
		public static decimal Round(decimal num, int decimals = 2, MidpointRounding mode = MidpointRounding.AwayFromZero)
		{
			return Math.Round(num, decimals, mode);
		}
		#endregion
	}
}
